﻿using FastExecutor.Base.Config;
using FastExecutor.Base.Util;
using FastExecutor.ORG.DB;
using FastExecutor.ORG.Entity;
using FastIOC.Annotation;
using FastORM.Applicaiton;
using FastUtil.Extra;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;

namespace FastExecutor.ORG.Util
{
    [Component]
    public class AuthUtil
    {
        private string TokenPrefix = System.Configuration.ConfigurationManager.AppSettings["TokenPrefix"];
        private string SessionTimeOut = System.Configuration.ConfigurationManager.AppSettings["SessionTimeOut"];
        [AutoWired]
        public DBUtil @DBUtil;
        [AutoWired]
        public DB_User @DB_User;
        [AutoWired]
        public DB_OU @DB_OU;
        [AutoWired]
        public DB_Module @DB_Module;
        [AutoWired]
        public DB_UserRoleRelation @DB_UserRoleRelation;
        [AutoWired]
        public DB_ModuleRight @DB_ModuleRight;
        public string CreateTokenKey(string UserGuid)
        {
            Frame_User user = @DB_User.FindOne(UserGuid);
            Frame_OU ou = @DB_OU.FindOne(user.OUGuid);
            string TokenKeyName = TokenPrefix + "_" + UserGuid + Guid.NewGuid().ToString();
            RedisUtil.SetHash(TokenKeyName, "UserGuid", user.RowGuid);
            RedisUtil.SetHash(TokenKeyName, "DisplayName", user.DisplayName);
            RedisUtil.SetHash(TokenKeyName, "LoginID", user.LoginID);
            RedisUtil.SetHash(TokenKeyName, "Mobile", user.Mobile);
            RedisUtil.SetHash(TokenKeyName, "EMail", user.Email);
            RedisUtil.SetHash(TokenKeyName, "OUGuid", user.OUGuid);
            RedisUtil.SetHash(TokenKeyName, "OUName", ou.OUName);
            RedisUtil.SetHash(TokenKeyName, "OUCode", ou.OUCode);
            RedisUtil.SetHash(TokenKeyName, "ParentOUGuid", ou.ParentOUGuid);
            RedisUtil.SetKeyExpire(TokenKeyName, TimeSpan.FromMinutes(Convert.ToDouble(SessionTimeOut)));
            return TokenKeyName;
        }
        public bool ValidToken(string TokenKey)
        {
            bool Valid = true;
            try
            {
                if (!RedisUtil.ExistKey(TokenKey))
                {
                    Valid = false;
                }
                if (!RedisUtil.ExistHash(TokenKey, "UserGuid"))
                {
                    Valid = false;
                }

                string UserGuid = RedisUtil.GetHash(TokenKey, "UserGuid");
                if (UserGuid == null || string.IsNullOrEmpty(UserGuid))
                {
                    Valid = false;
                }
            }
            catch (Exception e)
            {

                Valid = false;
            }
            return Valid;
        }
        public TokenEntity GetToken(string TokenKey)
        {
            TokenEntity Entity = new TokenEntity();
            Dictionary<string, object> dic = RedisUtil.GetAllHash(TokenKey);
            Entity.UserGuid = Convert.ToString(dic["UserGuid"]);
            Entity.DisplayName = Convert.ToString(dic["DisplayName"]);
            Entity.LoginID = Convert.ToString(dic["LoginID"]);
            Entity.Mobile = Convert.ToString(dic["Mobile"]);
            Entity.EMail = Convert.ToString(dic["EMail"]);
            Entity.OUGuid = Convert.ToString(dic["OUGuid"]);
            Entity.OUName = Convert.ToString(dic["OUName"]);
            Entity.ParentOUGuid = Convert.ToString(dic["ParentOUGuid"]);
            Entity.ParentOUGuid = Convert.ToString(dic["ParentOUGuid"]);
            return Entity;
        }
        public TokenEntity GetToken()
        {
            string TokenKey = GetTokenString();
            if (!string.IsNullOrEmpty(TokenKey))
            {
                TokenEntity Entity = new TokenEntity();
                Dictionary<string, object> dic = RedisUtil.GetAllHash(TokenKey);
                Entity.UserGuid = Convert.ToString(dic["UserGuid"]);
                Entity.DisplayName = Convert.ToString(dic["DisplayName"]);
                Entity.LoginID = Convert.ToString(dic["LoginID"]);
                Entity.Mobile = Convert.ToString(dic["Mobile"]);
                Entity.EMail = Convert.ToString(dic["EMail"]);
                Entity.OUGuid = Convert.ToString(dic["OUGuid"]);
                Entity.OUName = Convert.ToString(dic["OUName"]);
                Entity.ParentOUGuid = Convert.ToString(dic["ParentOUGuid"]);
                Entity.ParentOUGuid = Convert.ToString(dic["ParentOUGuid"]);
                return Entity;
            }
            else
            {
                return null;
            }
        }
        public string GetTokenString(HttpRequestBase Request)
        {
            var cookies = Request.Cookies;
            HttpCookie cookie = cookies[TokenPrefix];
            if (cookie == null)
            {
                return string.Empty;
            }
            else
            {
                return cookie.Values["token"];
            }

        }
        public string GetTokenString()
        {
            var cookies = System.Web.HttpContext.Current.Request.Cookies;
            HttpCookie cookie = cookies[TokenPrefix];
            if (cookie == null)
            {
                return string.Empty;
            }
            else
            {
                return cookie.Values["token"];
            }

        }
        public void SetTokenCookie(HttpRequestBase Request, HttpResponseBase Reponse, string Token)
        {
            //存储cookie
            var cookies = Request.Cookies;
            HttpCookie cookie = cookies[TokenPrefix];
            if (null == cookie)
            {
                cookie = new HttpCookie(TokenPrefix);//初使化并设置Cookie的名称
                DateTime dt = DateTime.Now;
                TimeSpan ts = TimeSpan.FromMinutes(Convert.ToInt32(SessionTimeOut));
                cookie.Expires = dt.Add(ts);//设置过期时间
                cookie.Values.Add("token", Token);
                Reponse.AppendCookie(cookie);
            }
            else
            {
                cookie.Values.Set("token", Token);
            }
        }
        public bool ValidCookie(HttpRequestBase Request)
        {
            var cookies = Request.Cookies;
            HttpCookie cookie = cookies[TokenPrefix];
            if (null == cookie)
            {
                return false;
            }
            else
            {
                return true;
            }
        }
        public bool CheckIsAnonymousAccess(string Url)
        {
            bool flag = false;
            AnonymousAccessSection Section = (AnonymousAccessSection)ConfigurationManager.GetSection("AnonymousAccess");
            for (int i = 0; i < Section.Pages.Count; i++)
            {
                if (Url.Contains(Section.Pages[i].Url))
                {
                    flag = true;
                    break;
                }
            }
            return flag;
        }
        public void RemoveAuth(HttpRequestBase Request, HttpResponseBase Reponse)
        {
            var cookies = Request.Cookies;
            HttpCookie cookie = cookies[TokenPrefix];
            RedisUtil.DelteKey(cookie.Values["token"]);
            cookie.Expires = DateTime.Now.AddDays(-3);
            HttpContext.Current.Response.Cookies.Add(cookie);
        }
        public void RefreshAuth(HttpRequestBase Request, HttpResponseBase Reponse)
        {
            var cookies = Request.Cookies;
            HttpCookie cookie = cookies[TokenPrefix];
            cookie.Expires = DateTime.Now.AddMinutes(Convert.ToDouble(SessionTimeOut));
            Reponse.SetCookie(cookie);
            RedisUtil.SetKeyExpire(cookie.Values["token"], TimeSpan.FromMinutes(Convert.ToDouble(SessionTimeOut)));
        }
        public bool CheckIsModule(string Url)
        {
            string ModuleUrl = Url.Replace(CommonUtil.GetRootPath(), "");
            List<Frame_Module> ModuletList = DB_Module.FindAll(string.Format(" and ModuleUrl='{0}'", Url));
            if (ModuletList.Count > 0)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        public bool CheckModuleRight(string UGuid, string DGuid, string Url)
        {
            string ModuleUrl = Url.Replace(CommonUtil.GetRootPath(), "");
            List<Frame_UserRolerelation> RelationList = @DB_UserRoleRelation.FindAll(string.Format(" and UserGuid='{0}'", UGuid));
            List<Frame_Module> ModuletList = @DB_Module.FindAll(string.Format(" and ModuleUrl='{0}'", Url));
            string RoleListStr = "";
            if (RelationList.Count > 0)
            {
                RoleListStr = "(";
                foreach (Frame_UserRolerelation item in RelationList)
                {
                    RoleListStr += string.Format("'{0}',", item.RoleGuid);
                }
                RoleListStr = RoleListStr.TrimEnd(',') + ")";
            }


            if (ModuletList.Count > 0)
            {
                string ModuleGuid = Convert.ToString(ModuletList[0].RowGuid);
                //个人设置
                string UserSQL = string.Format(" RightGuid='{0}'", UGuid);
                //部门设置
                string OUSQL = string.Format(" RightGuid='{0}'", DGuid);
                //角色设置
                string RoleSQL = string.Format(" RightGuid in {0} ", RoleListStr);
                string RightSQL = string.Format(" and ModuleGuid='{0}'", ModuleGuid);
                if (!string.IsNullOrEmpty(RoleListStr))
                {
                    RightSQL += string.Format(" and (({0}) or ({1}) or ({2}))", UserSQL, OUSQL, RoleSQL);
                }
                else
                {
                    RightSQL += string.Format(" and (({0}) or ({1}))", UserSQL, OUSQL);
                }
                List<Frame_ModuleRight> ModuleRightList = @DB_ModuleRight.FindAll(RightSQL);
                if (ModuleRightList.Count > 0)
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
            else
            {
                return false;
            }
        }
    }
}
